package JUC.singletonMode;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

// DCL饿汉式单例模式（利用volatile保证不被指令重排，利用锁机制保证多线程下单例,双检锁机制，减小锁的粒度（级别））
public class DclLazyMan {

    private volatile static DclLazyMan dclLazyMan;
    private DclLazyMan(){
        System.out.println(Thread.currentThread().getName()+" 执行了构造方法");
    }

    /*  生成一个对象的大致过程
    *  1 分配内存空间
    *  2 执行构造方法初始化对象
    *  3 把这个对象指向分配的空间
    *   其中由于指令重排2和3有可能会对调，线程A执行饿汉式单例模式的时候先把对象指向分配的空间，
    *   这个时候线程B再去执行会发现A还没有执行构造方法来初始化对象
    *   所以就判断dclLazyMan == null，所以直接new一个对象造成单例模式被破坏
    * */
    public static DclLazyMan getInstance(){
        if (dclLazyMan == null){
            synchronized (DclLazyMan.class){
                if (dclLazyMan == null){
                    dclLazyMan = new DclLazyMan();
                }
            }
        }
        return dclLazyMan;
    }

    public static void main(String[] args) {
        for (int i = 0;i<10;i++){
            new Thread(DclLazyMan::getInstance).start();
        }

        Lock lock =new ReentrantLock();
    }
}
